#pragma once

// SPSC
#include <atomic>

template <typename T,unsigned int Capacity>
class RingBuffer
{
public:
    //在类的定义中直接使用静态断言是一种非常常见且推荐的做法，尤其对于模板类，它能在编译期就对类型或常量进行有效性检查。
    static_assert(Capacity && !(Capacity & Capacity-1),"Capacity must be power of 2");
    
    RingBuffer():head_(0),tail_(0){}
    ~RingBuffer(){
        //切换线程，std::memory_order_relaxed会获取到最新值。这个函数主线程会调用
        unsigned int head = head_.load(std::memory_order_relaxed);
        unsigned int tail = tail_.load(std::memory_order_relaxed);
        while (head!=tail)
        {
            reinterpret_cast<T*>(&buffer_[head])->~T();
            head = (head+1)&(Capacity-1);
        }
    }

    // 这里使用万能引用和完美转发，支持左值和右值
    template <typename U>
    bool Push(U &&value){
        unsigned int tail = tail_.load(std::memory_order_relaxed);
        unsigned int tail_next = (tail+1)&(Capacity-1);
        if (tail_next == head_.load(std::memory_order_acquire))
        {
            return false;
        }
        new (&buffer_[tail]) T(std::forward<U>(value));
        tail_.store(tail_next,std::memory_order_release);
        return true;
    }

    bool Pop(T &value){
        unsigned int head = head_.load(std::memory_order_relaxed);
        if (head == tail_.load(std::memory_order_acquire))
        {
            return false;
        }
        value = std::move(*reinterpret_cast<T*>(&buffer_[head]));
        reinterpret_cast<T*>(&buffer_[head])->~T();
        head_.store((head+1)&(Capacity-1),std::memory_order_release);
        return true;
    }

    unsigned int Size(){
        unsigned int head = head_.load(std::memory_order_acquire);
        unsigned int tail = tail_.load(std::memory_order_acquire);
        return (tail>head)?(tail-head):(Capacity-head+tail);
    }

private:
    alignas(64) std::atomic<unsigned int> head_;
    alignas(64) std::atomic<unsigned int> tail_;
    alignas(64) std::aligned_storage_t<sizeof(T), alignof(T)> buffer_[Capacity];  // 支持 pod 和 非 pod 类型
};